/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Actors;

import Actors.Actor;
import java.awt.Dimension;
import java.awt.Shape;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.List;

/**
 * TODO: make the player manager detect collisions between actors, and send
 * those collisions back to the actor to respond.
 * @author Joshua Mabrey
 */
public class ActorManager {

    private static List<Actor> colliders, collidersCopy;
    private static List<ActorBounds> bounds, boundsCopy;
    private static Object BoundsListLock = new Object();

    public static void addToCollisionDetect(Actor a) {
        if (colliders == null) {
            colliders = new ArrayList<Actor>();
        }
        colliders.add(a);
    }

    public static void removeFromCollisionDetection(Actor a){
        if (colliders == null) {
            colliders = new ArrayList<Actor>();
        }
        if(colliders.contains(a)){
            colliders.remove(a);
        }
    }

    public static synchronized void update() {
        if (colliders == null) {
            colliders = new ArrayList<Actor>();
        }
        if (collidersCopy == null) {
            collidersCopy = new ArrayList<Actor>();
        }
        collidersCopy.clear();
        for (Actor a : colliders) {
            collidersCopy.add(a);
        }
        for (Actor a : colliders.toArray(new Actor[0])) {
            for (Actor b : colliders.toArray(new Actor[0])) {
                for (Shape s : a.collidableArea()) {
                    for (Shape t : b.collidableArea()) {
                        if (a != null && b != null && s != null && t != null && (!a.equals(b)) && s.getBounds2D().intersects(t.getBounds2D())
                                && (collidersCopy.contains(a)
                                && collidersCopy.contains(b))) {
                            //System.out.println("A: " + s.getBounds2D().toString());
                            //System.out.println("B: " + t.getBounds2D().toString());
                            a.collide(b);
                            b.collide(a);
                            if (a instanceof PlayerActor) {
                                collidersCopy.remove(a);
                            }
                            if (b instanceof PlayerActor) {
                                collidersCopy.remove(b);
                            }
                        }
                    }
                }
            }
        }

        for (Actor a : collidersCopy) {
            a.collide(null); //to let these actors know they collided with nothing this pass
        }
    }

    public static PlayerActor getPlayer(int up, int down, int left, int right) {
        return new PlayerActor(up, down, left, right);
    }

    public static void handleBounds(PlayerActor a) {
        /*synchronized (BoundsListLock) {


            if (bounds == null) {
                bounds = new ArrayList<ActorBounds>();
            }
            if (boundsCopy == null) {
                boundsCopy = new ArrayList<ActorBounds>();
            }
            boundsCopy.clear();

            for (ActorBounds b : bounds) {
                boundsCopy.add(b);
            }
            for (ActorBounds b : boundsCopy) {
                Rectangle2D d = b.bounds;
                if (b.inside) {
                    if (a.x < d.getMinX()) {
                        a.x = d.getMinX();
                    }
                    if (a.x > d.getMaxX()) {
                        a.x = d.getMaxX();
                    }
                    if (a.y < d.getMinY()) {
                        a.y = d.getMinY();
                    }
                    if (a.y > d.getMaxY()) {
                        a.y = d.getMaxY();
                    }
                } else {
                    
                    /*if ((a.x > d.getMinX() || a.x + PlayerActor.length > d.getMinX())
                            && (a.x < d.getMaxX() || a.x + PlayerActor.length < d.getMaxX())
                            && (a.y < d.getMaxY() || a.y + PlayerActor.length < d.getMaxY())
                            && (a.y > d.getMinY() || a.y + PlayerActor.length > d.getMinY())) {
                        a.revertLocation();
                    }
                    for(Shape s : a.collidableArea()){
                        if(s.getBounds2D().intersects(d.getBounds2D())){
                            a.revertLocation();
                        }
                    }
                }
                b.expiry--;
                if (b.expiry == 0) {
                    bounds.remove(b);
                }
            }
        }*/
    }

    public synchronized static void addBoundingShape(Shape s, boolean inside) {
        /*synchronized (BoundsListLock) {
            if (bounds == null) {
                bounds = new ArrayList<ActorBounds>();
            }
            bounds.add(new ActorBounds(s, inside));
        }*/
    }

    public synchronized static void tempAddBoundingShape(Shape s, boolean inside, short expiry) {
        /*synchronized (BoundsListLock) {
            if (bounds == null) {
                bounds = new ArrayList<ActorBounds>();
            }
            bounds.add(new ActorBounds(s, inside, expiry));
        }*/
    }
}
